package com.ghy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ghy.dto.CartInsertDTO;
import com.ghy.dto.CartPageDTO;
import com.ghy.dto.CartUpdateDTO;
import com.ghy.entity.Cart;
import com.ghy.entity.Course;
import com.ghy.entity.User;

import com.ghy.feign.CourseFeign;
import com.ghy.feign.UserFeign;
import com.ghy.vo.CartSimpleListVO;
import com.mybatisflex.core.query.QueryChain;

import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;

import com.ghy.mapper.CartMapper;
import com.ghy.service.CartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;

import java.util.List;

import static com.ghy.entity.table.CartTableDef.CART;

/**
 * 购物车表 服务层实现。
 *
 * @author ghy
 * @since 2024-12-22
 */
@Service
@CacheConfig(cacheNames = "cart")
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart>  implements CartService{


    @Autowired
    private UserFeign userFeign;
    @Autowired
    private CourseFeign courseFeign;

    @CacheEvict(allEntries = true)
    @Override
    public boolean insert(CartInsertDTO dto) {

        Course course = courseFeign.select(dto.getFkCourseId()).getData();

        if (ObjectUtil.isNull(course)){
            throw new RuntimeException("课程不存在");
        }

        User user = userFeign.select(dto.getFkUserId()).getData();

        if (ObjectUtil.isNull(course)){
            throw new RuntimeException("用户不存在");
        }



        //组装entity 实体类
        Cart cart = BeanUtil.copyProperties(dto, Cart.class);

        cart.setUsername(user.getUsername());
        cart.setCourseTitle(course.getTitle());
        cart.setCoursePrice(course.getPrice());
        cart.setCourseCover(course.getCover());
        cart.setCreated(LocalDateTime.now());
        cart.setUpdated(LocalDateTime.now());

        return mapper.insert(cart) > 0;
    }

    @Cacheable(key = "#p0",
            condition = "#p0 != null",
            unless = "#result == null")
    @Override
    public Cart select(Long id) {

        return mapper.selectOneWithRelationsById(id);
    }



    @Cacheable(key = "#root.methodName",
            unless = "#result == null")
    @Override
    public List<CartSimpleListVO> simpleList() {
        return QueryChain.of(mapper)
                .withRelations ()
                .listAs(CartSimpleListVO.class);
    }

    @Cacheable(key ="#root.methodName + ':' + #p0.toString()",
            condition = "#p0 != null",
            unless = "#result == null")
    @Override
    public Page<Cart> page(CartPageDTO dto) {
        QueryChain<Cart> queryChain = QueryChain.of(mapper);

        // fkUserId 条件
        Long fkUserId = dto.getFkUserId();
        if (ObjectUtil.isNotNull(fkUserId)) {
            queryChain.where(CART.FK_USER_ID.eq(fkUserId));
        }

        // fkCourseId 条件
        Long fkCourseId = dto.getFkCourseId();
        if (ObjectUtil.isNotNull(fkCourseId)) {
            queryChain.where(CART.FK_COURSE_ID.eq(fkCourseId));
        }

        // courseTitle 条件
        String courseTitle = dto.getCourseTitle();
        if (ObjectUtil.isNotEmpty(courseTitle)) {
            queryChain.where(CART.FK_COURSE_ID.eq(courseTitle));
        }

        return queryChain.withRelations()
                .page(new Page<>(dto.getPageNum(),dto.getPageSize()));
    }

    @CacheEvict(allEntries = true)
    @Override
    public Double totalAmountByUserId(Long id) {
        List<Cart> A =  QueryChain.of(mapper)
                .select(CART.COURSE_PRICE)
                .where(CART.FK_USER_ID.eq(id))
                .list();
        double total = 0.0;
        for (Cart item : A) {
            total += item.getCoursePrice();
        }
        return total;

    }
    @CacheEvict(allEntries = true)
    @Override
    public boolean cleanByUserId(Long id) {
        return UpdateChain.of(mapper)
                .where(CART.FK_USER_ID.eq(id))
                .remove();
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(CartUpdateDTO dto) {
        //组装entity实体类
        Cart cart = BeanUtil.copyProperties(dto, Cart.class);

        cart.setUpdated(LocalDateTime.now());

        return UpdateChain.of(cart)
                .where(CART.ID.eq(cart.getId()))
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean delete(Long id) {

        //删除父评论
        return mapper.deleteById(id) > 0;

    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteBatch(List<Long> ids) {

        //删除父评论
        return mapper.deleteBatchByIds(ids) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean clearByUserId(Long userId) {
        return UpdateChain.of(mapper)
                .where(CART.FK_USER_ID.eq(userId))
                .remove();
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteByUserIdAndCourseIds(Long userId, List<Long> courseIds) {
        return UpdateChain.of(mapper)
                .where(CART.FK_USER_ID.eq(userId))
                .and(CART.FK_COURSE_ID.in(courseIds))
                .remove();
    }
}
